home *** CD-ROM | disk | FTP | other *** search
- /** $VER: ARx_Help.ed 2.0a (28 Feb 1994,30 Mar 1994)
- ** by Robin Evans
- **
- ** Display the ARexxGuide page for the word currently under the cursor.
- ** Will call ARx_Setup.rexx if env: variables are not set.
- **
- ** Add the following line to the file S:Ed-Startup or whatever other file
- ** you use to set Ed's default configuration.
- **
- ** sf 1 "rx \arx_help\"
- **
- ** This will hook ARexxGuide into the F1 key. Consult a manual for
- ** other possible key assignments. The same command can also be issued
- ** from within an Ed session to make a temporary assignment. Just type
- ** in the command at a `*' prompt after pressing the <Esc> key. (Those
- ** who have been reading Denny Atkin's DOS column in AmigaWorld have
- ** learned that Ed has a far more comprehensive menu if the menu items
- ** in the Ed-Startup file are deleted.)
- **
- ** Environmental variables:
- ** env:AmigaGuide/path must include the directory where
- ** arx_guide.xref is located.
- ** env:ARexxGuide/AGCmd must hold the name of the command
- ** (probably something like `sys:utilities/Multiview') used to
- ** show launch amigaguide files.
- ** env:ARexxGuide/ShowFullHelp must be set to 1 if the rexxarplib
- ** information window is to be shown. rexxarplib.library is
- ** required for that feature only.
- **
- ** See `Tutorials: Help key macros' ( HELPKEYMACRO ) in ARexxGuide for more
- ** information about this macro.
- **/
-
- signal on syntax
- signal on break_c
- signal on halt
- signal on failure
-
- options results
- parse arg LkUp
-
-
- call addlib('rexxsupport.library',0,-30)
- call addlib('amigaguide.library',-1,-30)
-
- TRUE=1; FALSE=0
-
- /* Load the cross-ref file. Function returns quickly if the file is **
- ** already loaded, but -- like ADDLIB() it can return true even if **
- ** the file isn't available, so we check by looking for a known node.*/
- call DisplayStatus('ARx_Help: Checking .xref files...')
- do Attempt = 1
- call LoadXref('ARx_Guide.xref')
- if getxref('TRACEOPT1') = 10 then do /* Leave below */
- /* Did this in a loop just to be able to use signal for a no-load */
- if Attempt = 2 then
- signal XRefError
- else if 'ARx_Setup.rexx'('HELP',,address()) ~= 0 then signal XRefError
- end
- else leave Attempt
- end
-
- /* Add any extra files included in the env: variable. */
- ExtraXRef = GetEnv('ARexxGuide/XRFiles')
- do i = 1 for words(ExtraXRef)
- /* 'Call' because we don't care about errors here. */
- call loadxref(word(ExtraXRef, i))
- end
-
- call DisplayStatus('ARexxGuide online help system...')
-
- /* It isn't used in the setup provided here, but it's possible to **
- ** just pass a word as an argument to this routine and get a lookup **
- ** on that. */
- if LkUp = '' then do
- /* Get the current line and position. Editor's commands are all **
- ** in subroutines and not in the main code. */
- HLine = GetCLine()
- CurPos = GetCurPos()
- /* Show the index requester if it's a blank line */
- if HLine = '' | verify(HLine, ' ;') = 0 then do
- call ShowInfo(,, CurPos, Kwd)
- signal CleanExit
- end
-
- /* Cut a single clause out of preceding clauses */
- SemPos = lastpos(';', HLine, CurPos) + 1
- /* This will break if a semicolon is used within a string **
- ** but checking for that seems like overkill. */
- if SemPos > 1 then do
- if SemPos < CurPos + 1 then do
- parse var HLine =SemPos HLine ';'
- CurPos = CurPos - SemPos + 1
- end
- end
- /* Cut it out of following clauses */
- else
- parse var HLine HLine ';'
-
- /* The current keyword is used within MChar select clause */
- Kwd = upper(word(HLine, 1))
-
- /* Hex characters: SpTbRt */
- /* Check for special characters -- operators, quotation marks, etc */
- MChar = pos(substr(HLine,CurPos,1), '+-/*%|&^><=,;:~)("''?!.'||'20090a'x)
- select
- when MChar = 0 then do /* It isn't one of the chars */
- /* Look for whole word if it isn't a special character */
- LkUp = GetCWord(HLine, CurPos)
- end
- when MChar <= 5 then
- select
- when MChar <= 2 then /* + or - */
- if Kwd = 'PARSE' then
- LkUp = 'PARSETMP5'
- else
- LkUp = 'ARITHMETIC'
- when MChar <= 4 then do /* / or * */
- /* This picks up the three characters surrounding a '*' or '/' */
- ComChar = substr(HLine, max(1, CurPos - 1), 3)
- if pos('/*', ComChar) + pos('*/', ComChar) > 0 then
- LkUp = 'COMMENT'
- else
- LkUp = 'ARITHMETIC'
- end
- otherwise
- LkUp = 'ARITHMETIC' /* % */
- end
- when MChar <= 13 then
- select
- when MChar <= 8 then do /* | or & or ^ */
- /* This picks up the three characters surrounding token */
- ComChar = substr(HLine, max(1, CurPos - 1), 3)
- if pos('||', ComChar) > 0 then
- LkUp = 'CONCATENATION'
- else
- LkUp = 'LOGICAL'
- end
- when MChar <= 10 then /* < or > */
- LkUp = 'COMPARISON'
- when MChar = 11 then /* = */
- if Kwd = 'PARSE' then
- LkUp = 'PARSETMP5'
- else if symbol(strip(left(HLine, max(1, CurPos-1)))) == 'BAD' then
- LkUp = 'COMPARISON'
- else
- LkUp = 'ASSIGNMENT'
- when MChar = 12 then /* , */
- LkUp = 'COMMA'
- otherwise /* ; */
- LkUp = 'SEMICOLON'
- end
- when MChar <= 19 then
- select
- when MChar = 14 then /* : */
- LkUp = 'LABEL'
- when MChar = 15 then do /* ~ */
- /* is the next character a comparison operator? */
- if pos(substr(HLine, CurPos , 2), '~=~>~<') > 0 then
- LkUp = 'COMPARISON'
- else
- LkUp = 'LOGICAL'
- end
- when MChar <=17 then /* ) or ( */
- if Kwd = 'PARSE' then
- LkUp = 'PARSETMP5'
- else
- LkUp = 'PAREN'
- otherwise /* " or ' */
- LkUp = 'STRING'
- end
- otherwise
- select
- when MChar = 20 then /* ? */
- if Kwd = 'TRACE' then
- LkUp = 'TRACEOPT1'
- else
- LkUp = '?'
- when MChar = 21 then /* ! */
- if Kwd = 'TRACE' then
- LkUp = 'TRACEOPT2'
- else
- LkUp = '!'
- when MChar = 22 then do /* . -- dot */
- /* Get the surrounding ARexx token */
- StPos = verify(' 'HLine, '+-|/&=~\><^,;:()"'' ', 'M', lastpos(' ', ' 'HLine, CurPos))
- Token = substr(HLine, StPos, verify(HLine' ', '+-|/&=~\><^,;:()"'' ', M, CurPos) - StPos)
- select
- when Token = '.' then
- if Kwd = 'PARSE' then
- LkUp = 'PARSETMP2'
- else
- LkUp = Token
- when datatype(Token, 'N') then
- LkUp = 'NUMBER'
- when datatype(Token, 'S') then
- if datatype(left(Token,1),'M') | verify(Token, '!@#$', 'M') = 1
- then LkUp = 'COMPVAR'
- otherwise
- LkUp = Token
- end
- end
- otherwise /* At a space or EOL */
- if CurPos >= wordindex(HLine, 1) then
- LkUp = GetCWord(HLine, CurPos)
- else do
- call ShowInfo(HLine,, CurPos, Kwd)
- signal CleanExit
- end
- end
- end
-
-
- /* Check for special words like `command' in `address command' **
- ** and most of the subkeywords in instructions like DO. */
- if word(HLine, 1) ~= LkUp then do CheckOpt = 1 for 1 /* Let's us leave */
- if GetXRef(LkUp) = 10 | find('ARG PULL UPPER COMMAND', upper(LkUp)) > 0 then do
- if word(GetXRef(Kwd),3) = 2 then select
- when Kwd = 'DO' then do
- SpecWord = find('UNTIL WHILE TO FOR BY FOREVER ', upper(LkUp))
- if SpecWord > 0 then
- LkUp = word('DOOPT4 DOOPT4 DOOPT2 DOOPT3 DOOPT2 DOOPT5', SpecWord)
- end
- when Kwd = 'PARSE' then do
- SpecWord = find('ARG PULL EXTERNAL NUMERIC SOURCE VERSION VALUE VAR WITH', upper(LkUp))
- if SpecWord > 0 then do
- LkUp = 'PARSESRC'SpecWord
- if SpecWord = 9 then
- LkUp = 'PARSESRC7'
- end
- else
- LkUp = 'PARSETMP1'
- end
- when Kwd = 'OPTIONS' then
- if find('RESULTS PROMPT FAILAT CASHE ON OFF', upper(LkUp)) > 0 then
- LkUp = Kwd
- when Kwd = 'TRACE' then
- if verify(upper(right(LkUp,1)), 'IRACLENOBS') = 0 then
- LkUp = 'TRACEOPT'
- when Kwd = 'SIGNAL' then
- if find('ON OFF', upper(LkUp)) >0 then
- LkUp = 'SIGTRAP'
- else if pos('BREAK_', upper(LkUp)) = 1 then
- LkUp = 'BREAK_'
- else
- LkUp = 'SIGTRAN'
- when upper(LkUp) = 'UPPER' then
- if Kwd ~= 'UPPER' then
- LkUp = 'UPPER()'
- when Kwd = 'ADDRESS' then
- if abbrev(word(HLine, 2), LkUp) then do
- LkUp = Kwd
- leave CheckOpt /* so we don't get address() */
- end
- otherwise
- end
- if GetXRef(LkUp'()') ~= 10 then
- LkUp = LkUp'()'
- end
- end
- end
- else do /* Word was supplied as argument to the script */
- upper LkUp
- CurPos = 1; HLine = LkUp
- end
-
- XRVal = upper(GetXRef(LkUp))
- if find('10 NODE/K', XRVal) > 0 then do
- if ShowInfo( HLine, LkUp, CurPos, Kwd ) = 0 then signal CleanExit
- else XRVal = upper(GetXRef(LkUp))
- end
-
- if ~abbrev(word(XRVal,2), '"ARX_') then
- Src = 'Other ref:'
- else
- Src = 'ARexxGuide:'
- call DisplayStatus(Src upper(LkUp) '['word('Explanation Function Instruction', word(getxref(LkUp), 3)+1)']')
-
- signal on error
- call DisplayAG(LkUp)
- signal off error
-
- CleanExit:
- /* Since it can cause severe problems, it's removed when not needed */
- call remlib('amigaguide.library')
- call EditorExit()
- exit 0
-
- /*************************************************************************
- ** Error routines. */
-
- XRefError:
- ErrMsg = 'Unable to load the cross-reference file ARx_Guide.xref\'
- if ~exists('env:amigaguide/path') then
- ErrMsg = ErrMsg || 'Your environmental variable "amigaguide/path" is not set.\'
- else
- ErrMsg = ErrMsg ' Be sure to include that file''s directory in env:amigaguide/path.\'
- ErrMsg = ErrMsg ' The .xref file may be put into the current directory or into\',
- ' any directory included in the amigaguide/path environmental variable.'
- call PutErrMsg(SIGL, ErrMsg)
- exit 6
- NoCmd:
- call PutErrMsg(SIGL, 'Can''t read environmental variable "env:arexxguide/AGcmd".\',
- ' That variable must hold the name of the command you use\',
- ' to show AmigaGuide files.')
- exit 7
- Syntax:
- call PutErrMsg(SIGL, ' Syntax error #'rc ':' errortext(rc))
- exit 9
- Failure:
- call PutErrMsg(SIGL, ' Command "'sourceline(SIGL)'" failed.')
- exit 10
- Halt:
- Break_C:
- call PutErrMsg(SIGL, ' Execution halted.')
- exit 8
- Error:
- call PutErrMsg(SIGL, ' Command error in display routine: RC =' rc'.\\',
- ' The name of your AmigaGuide viewer may not be properly set, or\',
- ' an .xref file might have been loaded for a database not located\',
- ' in one of the directories in env:AmigaGuide/path.\',
- ' Type rx ARx_Setup at a shell prompt to run the setup program again.')
- exit 9
- PutErrMsg:
- call trace b
- ErrMsg ='Sorry an enexpected error has occurred in line' arg(1)'.\\'arg(2)
- signal off syntax
- signal off halt
- signal off break_c
- WinHi = 59 + CountChar('\', ErrMsg) * 11
- call DisplayStatus('ARx_Help macro error.')
- if open(6ErrWin, 'raw:0/0/640/'WinHi'/Arx_Help Error/SCREEN *') then do
- call writeln(6ErrWin, translate(ErrMsg,'0a'x, '\'))
- call writech(6ErrWin, '0a'x' -- Press any key -- ')
- call readch(6ErrWin)
- end
- call EditorExit()
- return 0
-
- exit 0
-
- /*************************************************************************
- ** General utility routines */
-
- GetAGCmd: procedure
- /* Calls the setup program if env:ARexxGuide/AGCmd is not set */
- AGCmd = GetEnv('ARexxGuide/AGCmd')
- if AGCmd = '' then do
- call DisplayStatus('Please wait... Running setup routine')
- if 'ARx_Setup.rexx'('HELP',,address()) ~= 0 then
- signal NoCmd
- else
- AGCmd = GetEnv('ARexxGuide/AGCmd')
- end
- return AGCmd
-
- ShowInfo:
- /* The env: var ShowFullHelp determines whether a simple editor **
- ** requester is used, or a complex rexxarplib window that displays **
- ** far more information about the current line, but is also slow. */
- if getenv('ARexxGuide/ShowFullHelp') ~= '1' then do
- if BoolReq(upper(LkUp) 'not found.','Show ARexxGuide index?') then do
- LkUp = 'ARx_NdxCont'
- return 1
- end
- else
- return 0
- end
- else do
- /* Show that we're doing something */
- call DisplayStatus(LkUp 'not found. Checking clause...')
-
- /* The .rexx part of the name has to be added because the default **
- ** extension is set by editor: .TTX, .edge, etc. Since this **
- ** is set up for different editors, it's stored with the generic **
- ** extension. */
- return 'ARx_RArpInfoWin.rexx'(HLine,LkUp,CurPos,Kwd,SetAddress(),SetExecStr(),GetWinInfo())
- end
-
- CountChar:
- return length(arg(2)) - length(compress(arg(2), arg(1)))
-
- GetEnv: procedure
- /* Arguments: **
- ** arg(1) := The name of the variable to retrieve **
- ** Returns a string */
-
- /* Use external function of same name if it's available */
- if show('L', 'rexxarplib.library') then
- return 'GetEnv'(arg(1))
- /* OPEN() will fail if variable is not defined. Null will be **
- ** returned in that case */
- if open(6Env, 'env:'arg(1), 'R') then do
- EnvVar = readln(6Env)
- call close 6Env
- end
- else EnvVar = ''
- return EnvVar
-
- Tab2Space: procedure
- parse arg TSize, Line
- tpos=pos('09'x,Line);
- do while tpos>0;
- Line=insert('',Line, tpos, min(1, tpos//TSize)*(TSize-tpos//TSize));
- tpos=pos('09'x, Line,tpos+1);
- end;
- return translate(Line,' ','09'x)
-
-
- /***********************************************************************
- ** Editor-specific commands. **
- ** These function calls are used elsewhere to make it easier to **
- ** use the same script for different editors. */
-
-
- GetCLine: procedure expose EdInfo.
- 'rv' '/EdInfo/'
- if rc ~= 0 then signal error
- return EdInfo.Current
-
- GetCurPos: procedure expose EdInfo.
- if symbol('EdInfo.X') ~= 'VAR' then do
- 'rv' '/EdInfo/'
- if rc ~= 0 then signal error
- end
- return EdInfo.Base + EdInfo.X
-
- GetCWord: procedure
- /* Send back current word */
- parse arg Line, CPos
- /* list of valid word-separator charaters: space, operator, spec char */
- SepChar = ' +-*/%|&~=><^,;:()."''\'
- /* Back up in line if Current position is not an alpha character or digit */
- do while (verify(substr(Line,CPos,1), SepChar || '0a'x) = 0) & (CPos > 1)
- CPos = CPos - 1
- end
- /* Cut off word at space _or_ any of the operator or special characters */
- Word = reverse(left(Line,verify(Line' ',SepChar,'M',CPos) - 1))
- return reverse(left(Word,verify(Word' ',SepChar,'M', max(1,length(Word) + 1 - CPos))-1))
-
- DisplayStatus:
- /* Put message in title bar of editor */
- 'sm' '"'arg(1)'"'
- return 0
-
- BoolReq: procedure
- /* Present a Yes/No requester **
- ** Arguments: **
- ** arg(1) := Titlebar text **
- ** arg(2) := Message in body of requester */
- if show('L', 'rexxreqtools.library') then
- return rtezrequest(arg(2), '_Yes|_No', arg(1))
- csi='9b'x;bold=csi'1m';norm=csi'0m';black=csi'31m';white=csi'32m';blue=csi'33m'
- if open(6InfoWin, 'raw:50/50/300/78/'arg(1)'/') then do
- call writeln(6InfoWin, csi'302070'x || '0a'x || center(arg(2),58))
- call writeln(6InfoWin, '0a'x blue ' Respond' white||bold'y'norm||blue 'or' white||bold'n'blue||norm'.')
- call writech(6InfoWin, black ' [<'white'Enter'black'> =' white'Y'black'. <'white'Esc'black'> =' white'N'black']')
- resp = readch(6InfoWin)
- call close 6InfoWin
- return (upper(resp) = 'Y' | resp = '0d'x)
- end
-
- GetWinInfo:
- /* Return Information about window **
- ** Format of returned value: **
- ** word 1 = x position **
- ** word 2 - y position **
- ** word 3 = name of public screen */
- /* Can't get window info for ed. */
- return 0 0 ""
-
- EditorExit:
- /* Used for any editor-specific commands that should be issued on **
- ** exit. */
- return 0
-
- SetExecStr:
- /* The string returned by this function is used in the rexxarplib **
- ** window to send link commands to AmigaGuide. */
- AGCmd = GetEnv('arexxguide/agcmd')
- if AGCmd = '' then do
- NoCmd_Return = 'ReShowInfo'
- signal NoCmd
- end
- if ~abbrev(AGCmd, 'Multi') then
- return 'address ARX_ARP quit; if ~show(P, ARX_GUIDE) then do;address command; ''run >nil:' AGCmd 'ARexxGuide.guide portname ARX_GUIDE'';waitforport ARX_GUIDE; end; address ARX_GUIDE; windowtofront; link'
- else
- return 'address ARX_ARP quit; address command; ''run' AGCmd 'document'
-
- SetAddress:
- /* Address used as target of the commands from rarp window */
- return 'ARX_HELP'
-
- DisplayAG:
- /* Show the node in AmigaGuide viewer. Missing env: will call **
- ** error handler which runs the setup prg. and then passes **
- ** control back to here. */
- arg LkUp
- AGCmd = GetEnv('arexxguide/agcmd')
- if AGCmd = '' then do
- NoCmd_Return = 'ShowFunc'
- signal NoCmd
- end
-
-
- if abbrev(AGCmd, 'Multi') then
- PrtOpt = ''
- else
- PrtOpt = 'portname ARX_GUIDE'
-
- /* See if our AG window is open */
- if ~show('P','ARX_GUIDE') then do
- if pos('/', LkUp) > 0 then
- parse var LkUp DB '/' Doc
- else
- DB = ''
- address command 'run' AGCmd DB 'document' LkUp PrtOpt 'requester'
- if rc > 5 then do
- NoCmd_Return = 'ShowFunc'
- signal NoCmd
- end
-
- end
- else do
- /* show the node */
- address ARX_GUIDE 'Link' LkUp
- address ARX_GUIDE 'unzoomwindow'
- address ARX_GUIDE 'windowtofront'
- /* This will be called only if rexxarplib is available and will **
- ** try to bring a public screen to the foreground. OK if there **
- ** isn't a screen of that name available. */
- if show('L', 'rexxarplib.library') then
- call screentofront('ARX_GUIDE')
- end
- return 0
-